package com.example.memloader;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

// 
public class Reflector {

	// invoke static method
	public static Object invokeStaticMethod(String strClassName, 
											String strMethodName,
											Class<?>[] clsParamTypes,
											Object[] objParamValues) {		
		try {
			Class<?> classobj = Class.forName(strClassName);
			Method method = classobj.getMethod(strMethodName, clsParamTypes);
			if (method == null) {
				 method = classobj.getDeclaredMethod(strMethodName, clsParamTypes);
			}
			method.setAccessible(true);
			return method.invoke(null, objParamValues);	//static call, obj should be null			
		}  catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		
		return null;
	}

	// invoke this.method
	public static Object invokeMethod(String strClassName, 
									String strMethodName,
									Class<?>[] clsParamTypes,
							        Object[] objParamValues) {
		 
		try {
			Class<?> objclass = Class.forName(strClassName);
			Method method = objclass.getMethod(strMethodName, clsParamTypes);
			if (method == null) {
				method = objclass.getDeclaredMethod(strMethodName, clsParamTypes);
			}
			method.setAccessible(true);
			return method.invoke(objclass, objParamValues);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;		
	}
	
	// get unaccessible variable 
	public static Object getDeclaredFieldObject(String strClassName, Object obj, String strFiledName){
		try {
			Class<?> objClass = Class.forName(strClassName);
			Field field = objClass.getDeclaredField(strClassName);
			field.setAccessible(true);
			return field.get(obj);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
	
	// get static variable
	public static Object getStaticFieldObject(String strClassName, String strFiledName){
		
		try {
			Class<?>  myClass = Class.forName(strClassName);
			Field field = myClass.getDeclaredField(strFiledName);
			field.setAccessible(true);
			return field.get(null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;		
	}
	
	// set unaccessible variable
	public static void setDeclaredFieldObject(String strClassName, String strFiledName,
											  Object obj, Object  objFieldValue) {
		try {
			Class<?> myClass = Class.forName(strClassName);
			Field field = myClass.getDeclaredField(strFiledName);
			field.setAccessible(true);
			field.set(obj, objFieldValue);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
	
	// set static variable
	public static void setStaticFieldObject(String strClassName, String strFiledName, Object objFiledValue) {	
		
		try {
			Class<?> myClass = Class.forName(strClassName);
			Field field = myClass.getDeclaredField(strFiledName);
			field.setAccessible(true);
			field.set(null, objFiledValue);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}

}	//end class
